﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.ETL.Domain.Services
{
    /// <summary>
    /// 手动执行操作的服务
    /// </summary>
    public class ManualService
    {
        /// <summary>
        /// 手动执行编码转换
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="dtTableId"></param>
        /// <returns></returns>
        public ServiceResult ConvertCCR(string userId, Guid dtTableId)
        {
            string taskKey = string.Format("ManualService.ConvertCCR:{0}", dtTableId);
            if (CPPEI.ETL.Domain.TaskKeeper.Exist(taskKey))
            {
                return new ServiceResult(false, ErrorCode.COM_InvalidParameter, "该数据表正在转换中，不能再操作");
            }

            if (dtTableId == Guid.Empty)
            {
                return new ServiceResult(false, ErrorCode.COM_InvalidParameter, ErrorCode.String(ErrorCode.COM_InvalidParameter));
            }

            CPPEI.ETL.Domain.TaskKeeper.Register(taskKey);

            try
            {
                using (EtlDbContext dbContext = new EtlDbContext())
                {
                    EntityRepository<Views.VCodeConversionRule> ccrRep = new EntityRepository<Views.VCodeConversionRule>(dbContext);

                    List<Views.VCodeConversionRule> eCCRList = ccrRep.Query(p => p.DtTableId == dtTableId).ToList();
                    if (eCCRList.Count == 0)
                    {
                        CPPEI.ETL.Domain.TaskKeeper.Unregister(taskKey);

                        return new ServiceResult(true, ErrorCode.COM_NoError, string.Empty);
                    }

                    EntityRepository<Entities.EDtTable> dtRep = new EntityRepository<Entities.EDtTable>(dbContext);
                    Entities.EDtTable eTable = dtRep.Get(p => p.Id == dtTableId);

                    EntityRepository<Entities.EDtTableColumn> dtcRep = new EntityRepository<Entities.EDtTableColumn>(dbContext);

                    List<Entities.EDtTableColumn> dtColumns = dtcRep.GetList(p => p.DtTableId == dtTableId);

                    List<string> columns = new List<string>();
                    List<string> pks = new List<string>();
                    for (int index = 0; index < dtColumns.Count; index++)
                    {
                        Entities.EDtTableColumn vDtColumn = dtColumns[index];

                        bool hasAdded = false;
                        for (int ccrIndex = 0; ccrIndex < eCCRList.Count; ccrIndex++)
                        {
                            if (eCCRList[ccrIndex].DtColumnId == vDtColumn.Id)
                            {
                                columns.Add(vDtColumn.Name);
                                hasAdded = true;
                                break;
                            }
                        }

                        if (vDtColumn.PK)
                        {
                            pks.Add(vDtColumn.Name);
                            if (hasAdded == false)
                            {
                                columns.Add(vDtColumn.Name);
                            }
                        }
                    }

                    if(eTable.IsRawDt)
                    {
                        // 加入系统默认的主键
                        pks.Add(DEF.DtTableColumns.SYSCOL_Id);
                        columns.Add(DEF.DtTableColumns.SYSCOL_Id);
                    }

                    System.Data.DataTable dataTable = CPPEI.ETL.Domain.Util.DtTableUtil.GetDataFromTableWithWhere(dbContext,
                            eTable.ActualName,
                            columns, null);

                    Dictionary<string, string> pkDict = new Dictionary<string, string>();
                    bool hasError = false;
                    for (int index = 0; index < dataTable.Rows.Count; index++)
                    {
                        DataRow dtRow = dataTable.Rows[index];
                        bool needUpdate = false;

                        List<string> udColumns = new List<string>();
                        List<string> udValues = new List<string>();
                        // 获取需要转化的列的值，判断是否需要转换，如果需要转化就更新数据库
                        for (int ccrIndex = 0; ccrIndex < eCCRList.Count; ccrIndex++)
                        {
                            string[] rawCodes = eCCRList[ccrIndex].RawCodes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                            string oldValue = Convert.ToString(dtRow[eCCRList[ccrIndex].DtColumnName]);
                            if (rawCodes.Contains(oldValue))
                            {
                                udColumns.Add(eCCRList[ccrIndex].DtColumnName);
                                udValues.Add(eCCRList[ccrIndex].DimItemCode);
                                // 更新数据
                                needUpdate = true;
                            }
                        }

                        if (needUpdate)
                        {
                            List<string> pkValues = new List<string>();
                            // 获取pk
                            for (int pkIndex = 0; pkIndex < pks.Count; pkIndex++)
                            {
                                pkValues.Add(Convert.ToString(dtRow[pks[pkIndex]]));
                            }

                            if (!CPPEI.ETL.Domain.Util.DtTableUtil.UpdateDataValueToTable(dbContext, eTable.ActualName, pks.ToArray(), pkValues.ToArray(),
                                udColumns.ToArray(),
                                udValues.ToArray()))
                            {
                                hasError = true;
                                break;
                            }
                        }

                    }

                    if (hasError)
                    {
                        CPPEI.ETL.Domain.TaskKeeper.Unregister(taskKey);
                        return new ServiceResult(false, 1, "删除数据失败,发生了错误");
                    }
                    else
                    {
                        CPPEI.ETL.Domain.TaskKeeper.Unregister(taskKey);
                        return new ServiceResult(true, ErrorCode.COM_NoError, string.Empty);
                    }
                }
            }
            catch (Exception ex)
            {
                CPPEI.ETL.Domain.TaskKeeper.Unregister(taskKey);
                return new ServiceResult(false, ErrorCode.COM_InvalidParameter, "发生了异常");
            }
        }
    }
}